package com.jewaton.auth.shiro;

import com.jewaton.auth.commons.entity.Account;
import com.jewaton.auth.commons.service.AccountService;
import com.jewaton.auth.commons.util.Constants;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.SessionListener;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Set;

@Repository("shiroSessionListener")
public class ShiroSessionListener implements SessionListener {

    @Resource(name="accountService")
    private AccountService accountService;
    @Resource(name="cacheManager")
    private CacheManager cacheManager;
    

	@Override
    public void onStart(Session session) {

    }

    @Override
    public void onStop(Session session) {

    }

    @Override
    @Transactional
    public void onExpiration(Session session) {
    	Cache cache = cacheManager.getCache("menu");
        PrincipalCollection principal= (PrincipalCollection) session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
        if (principal == null) return;
        Set<String> realmNames = principal.getRealmNames();
        if (realmNames.contains(Constants.ACCOUNT_REALM)) {
            //清理权限缓存
            accountService.clearCachedAuthorizationInfoOnSessionExpiration(principal);
            Account account = (Account) session.getAttribute(Constants.SESSION_PC_ACCOUNT);
            if (account != null) {
                Account nAccount = accountService.getAccountById(account.getAid());
                nAccount.setLastSigninTime(account.getLoginTime());
                nAccount.setLastSigninIp(account.getLoginIp());
                //清理菜单缓存
                cache.evict("pcmenu"+account.getAid());
                accountService.updateAccount(nAccount);
            }
        } 
    }
    
    
    
    public void setAccountService(AccountService accountService) {
        this.accountService = accountService;
    }


    public void setCacheManager(CacheManager cacheManager) {
        this.cacheManager = cacheManager;
    }

}
